package com.ming.attendance.service.impl;

import com.ming.attendance.Jobs.UnbindJob;
import com.ming.attendance.mapper.AttendanceEventMapper;
import com.ming.attendance.mapper.BeaconMapper;
import com.ming.attendance.mapper.EventUserMapper;
import com.ming.attendance.model.AttendanceEventCreateModel;
import com.ming.attendance.po.*;
import com.ming.attendance.service.AttendanceEventService;
import com.ming.attendance.service.EventUserService;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class AttendanceEventServiceImpl implements AttendanceEventService {
    @Autowired
    private AttendanceEventMapper aem;
    @Autowired
    private BeaconMapper bm;
    @Autowired
    private EventUserService eus;
    @Autowired
    private EventUserMapper eum;

    /** 创建事件，需要两步
     *  1. 创建事件
     *  2. 创建事件和创建者的关系
     *  注意，二者为同一事务，需要加注@Transactional注解
     *
     * @param event
     * @return
     */
    @Override
    @Transactional
    public ResponseBean<String> createEvent(AttendanceEventCreateModel event) {
        // // 1.创建事件
        // JSONObject jsonObject = JSONObject.parseObject(event.getBeaconId());
        // // 解析Beacon数据
        // Beacon beacon = JSONObject.parseObject(event.getBeaconId(), Beacon.class);

        Beacon beacon = event.getBeacon();
        Beacon beacon_old = bm.getBeaconByThree(beacon);    // 检查数据库中有没有该beacon，有则返回
        String beaconId = "";   // 时间结束时要解绑更改using的beaconId

        if(beacon_old!=null){   // 数据库存在该Beacon
            if(beacon_old.getUsing()==1){   // 该Beacon被使用
                return new ResponseBean<>(604,"这个beacon正在使用中，请更换beacon");
            }else{      // 该Beacon未被使用
                beacon_old.setUsing(1);
                bm.updateBeacon(beacon_old);    // 改beacon的using值
                event.setBeacon(beacon_old);
                event.setBeaconId(beacon_old.getBeaconId());

                beaconId = beacon_old.getBeaconId();    // 设定之后事件结束时要改便using的beaconId值
            }
        }else{          // 如果数据库中没有该beacon，就将其添加到库中
            beaconId = UUID.randomUUID().toString();
            beacon.setBeaconId(beaconId);
            beacon.setUsing(1);
            bm.addBeacon(beacon);
            event.setBeaconId(beaconId);
        }

        // 添加事件ID和创建时间
        event.setEventid(UUID.randomUUID().toString());
        event.setCreateTime(String.valueOf(new Date().getTime()));
        // 创建新事件
        int result = aem.createEvent(event);

        // 2.创建关系
        EventUser eventUser = new EventUser();
        eventUser.setEventid(event.getEventid());
        eventUser.setOpenid(event.getOpenid());
        ResponseBean<Integer> result2 = eus.createEventUser(eventUser);

        // 3.设置解绑Beacon的定时任务
        try {
            //   1. 创建调度器Scheduler
            StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();
            Scheduler scheduler = schedulerFactory.getScheduler();
            //   2. 创建JobDetail实例，并与定时任务类进行绑定(Job)
            JobDetail jobDetail = JobBuilder.newJob(UnbindJob.class)
                    .usingJobData("beaconId",beaconId)
                    .withIdentity("job1", "group1")
                    .build();
            //   3. 构建Trigger实例，设置执行时间
            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity("trigger1", "triggerGroup1")
                    .startAt(new Date(Long.parseLong(event.getDeadline()))) // 在事件结束时触发
                    // .startAt(new Date(new Date().getTime()+5000))    // 测试
                    .build();
            //   4. 执行
            scheduler.scheduleJob(jobDetail,trigger);
            System.out.println("-------------scheduler start !-------------");
            scheduler.start();

            //
            // //   睡眠
            // TimeUnit.MINUTES.sleep(1);
            // scheduler.shutdown();

        } catch (SchedulerException e) {
            e.printStackTrace();
        }

        // 结束返回
        if(result != 0 && result2.getCode()==200){
            return new ResponseBean<>(event.getEventid());
        }else{
            return new ResponseBean<>(602,"创建失败");
        }
    }

    @Override
    public ResponseBean<Integer> updateEvent(AttendanceEvent event) {
        int result = aem.updateEvent(event);
        if(result != 0){
            return new ResponseBean<>(result);
        }else{
            return new ResponseBean<>(603,"修改失败");
        }
    }

    @Override
    public ResponseBean<Integer> initEvent(AttendanceEvent event) {
        AttendanceEvent event1 = aem.getEvent(event.getEventid());
        if(event1.getOpengid()!=null) {
            return new ResponseBean<>(606, "初始化已完成");
        }
        int result = aem.updateEvent(event);
        if(result != 0){
            return new ResponseBean<>(result);
        }else{
            return new ResponseBean<>(603,"修改失败");
        }
    }

    @Override
    public ResponseBean<AttendanceEvent> getEvent(String eventid) {
        AttendanceEvent event = aem.getEvent(eventid);
        if(event!=null){
            return new ResponseBean<>(event);
        }else{
            return new ResponseBean<>(601,"没有该事件");
        }
    }

    @Override
    public ResponseBean<List<AttendanceEvent>> getEventsByOpenid(String openid) {
        List<AttendanceEvent> list = aem.getEventsByOpenid(openid);
        if(list!=null){
            return new ResponseBean<>(list);
        }else{
            return new ResponseBean<>(601,"没有相关事件");
        }
    }

    @Override
    @Transactional
    public ResponseBean<Integer> deleteEvent(AttendanceEvent event) {
        // 构造参数
        String eventid = event.getEventid();
        EventUser eventUser = new EventUser();
        eventUser.setEventid(eventid);

        Beacon beacon = new Beacon();
        beacon.setBeaconId(event.getBeaconId());

        int result1 = eum.deleteEventUser(eventUser);   // 先删关系
        if(result1 != 0){
            int result2 = aem.deleteEvent(event);       // 再删事件
            if(result2 != 0){
                // 解绑
                beacon.setUsing(0);
                int result3 = bm.updateBeacon(beacon);        // 最后解绑Beacon
                return new ResponseBean<>(result1);
            }
        }
        return new ResponseBean<>(607,"删除失败");
    }


}
